package com.fs.uc.core.permcheck;

import com.fs.uc.base.domain.*;
import com.fs.uc.base.repo.OrgRepository;
import com.fs.uc.core.CacheName;
import io.quarkus.cache.CacheResult;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.HashSet;
import java.util.Set;

/**
 * @author 崔超
 * 2021/12/9
 */
@ApplicationScoped
class OrgPermissionChecker implements IPermissionChecker {
    @Inject
    OrgRepository orgRepo;

    /*
    检查组织用户是否有对resource的action权限
     */
    @Override
    public boolean checkPermission(Long orgId, String action, String resource) {
        Set<Permission> permOfOrgUser = getPermissions(orgId);
        return PermissionCompare.comparePermissions(action, resource, permOfOrgUser);
    }


    @CacheResult(cacheName = CacheName.ORG_PERMISSION)
    @Override
    public Set<Permission> getPermissions(Long orgId) {
        Set<Role> ownRolesOfOrgUser = getRoles(orgId);
        Set<Permission> permissions = new HashSet<>();

        for (Role role : ownRolesOfOrgUser) {
            permissions.addAll(role.permissions);
        }
        return permissions;
    }

    /*
    获取组织用户本身拥有的角色
     */
    @Override
    public Set<Role> getRoles(Long orgId) {
        Set<FunctionalModule> authorizedModules = getAuthorizedModule(orgId);
        Set<Role> roleSet = new HashSet<>();

        for (FunctionalModule module : authorizedModules) {
            for (Role role : module.roles) {
                if (role.type == RoleType.ParkOriented) {
                    roleSet.add(role);
                }
            }
        }
        return roleSet;
    }

    @Override
    public Set<FunctionalModule> getAuthorizedModule(Long orgId) {
        Org org = orgRepo.getById(orgId);
        Set<FunctionalModule> sets = new HashSet<>(org.functionalModules);
        if (org.parent != null) {
            sets.addAll(org.parent.functionalModules);
        }
        return sets;
    }

    @CacheResult(cacheName = CacheName.ORG_SUBJECT)
    @Override
    public SubjectInfo getSubjectInfo(Long orgId) {
        Org org = orgRepo.getById(orgId);
        if (org.type == OrgType.Park) {
            return new SubjectInfo(org.id, org.id, 0L, org.name);
        } else {
            if (org.parent == null) {
                return new SubjectInfo(0L, org.id, 0L, org.name);
            }
            return new SubjectInfo(org.parent.id, org.id, 0L, org.name);
        }
    }
}
